home *** CD-ROM | disk | FTP | other *** search
- ; filename:RVB1.ASM
- ;
- ; This version of the reverberation program was written with the
- ; objective of maintaining clarity, so one may easily vary different
- ; parameters to hear their affect on the sound. To this end, it was
- ; necessary to limit the use of the parallel moves. Additionally,
- ; there may be superflous MOVES and CLR instructions, to allow
- ; one to disable certain functional blocks while still operating
- ; other algorithm parts. Final code implementation should
- ; eventually use the parallel move feature to reduce code size
- ; and execution time.
- ;
- ; Motorola DSP Group
- ; Austin, Tx
- ;
- ;**************************************************************************
- ; This program was originally available on the Motorola DSP bulletin board
- ; and is provided under a DISCLAIMER OF WARRANTY available from Motorola
- ; DSP Operation, 6501 William Cannon Dr. W Austin, Texas 78735-8598.
- ;**************************************************************************
- ;--------------------------------------------------------------------------
- ; This reverberation program is a variation of the reverberation
- ; system and structures as described by James Moorer's article entitled
- ; 'About this Reverberation Business', Computer Music Journal,
- ; 3(2):13-28, 1979
- ;
- ; Structure is:
- ; .----------.
- ; .------------. .-----. | All Pass |
- ; +->| Comb Filter|-->| SUM |-->| Reverb |
- ; Note: All Comb | | #1 | '-----' | |
- ; Filters | '------------' ^ ^ ^ '----------'
- ; Have a 1st | .------------. | | | |
- ; Order IIR |->| Comb Filter|---+ | | .---V---.
- ; LPF in their | | #2 | | | | align |
- ; feedback | '------------' | | | delay |
- ; loop | .------------. | | '---|---'
- ; |->| Comb Filter|------+ | |
- ; | | #3 | | ----- reverb
- ; | '------------' | \./ gain
- ; | .------------. | |
- ; |->| Comb Filter|---------+ |
- ; | | #4 | |
- ; | '------------' |
- ; | V
- ; .------------. | FIR gain .----------.
- ; | Early | | |\ | |
- ;input -->| Reflection |--+---------| >------------>| summer |--- output
- ; | | FIR | |/ | |
- ; | '------------' '----------'
- ; | ^
- ; | |
- ; | dry gain |
- ; | |\ |
- ; +------------------------------| >----------------+
- ; |/
- ;
- ;.............................................................................
- ; COMB FILTER SUB STRUCTURE:
- ; .-------.
- ; comb i .-----. | long | comb i
- ; input ------>| sum |---->| delay |-------+---------> output
- ; '-----' '-------' |
- ; ^ |
- ; | V
- ; | /| .-----.
- ; +-----< ------------| sum |<--------+
- ; \| '-----' |
- ; fdbck i | / \ lpf i gain
- ; gain V /_____\
- ; .----------. |
- ; | 1 sample | |
- ; | delay |-----+
- ; '----------'
- ;.............................................................................
- ; UNIT (ALL PASS) REVERBERATOR STRUCTURE:
- ; based on Schroeder as outlined in Griesinger: 'Practical Processors and
- ; Programs for Digital Reverberation', Audio in Digital Times, 7th AES
- ; conference, Toronto, Ontario, 1989
- ; (the structure outlined in Moorer is a variation of this)
- ;
- ; -g
- ; |\
- ; +---------->| >--------------------------+
- ; | |/ |
- ; | |
- ; | V
- ; unit | .-----. .--------. |\ .-----. unit
- ; input ------+--->| sum |-->| delay |--+--->| >-->| sum |-----> output
- ; '-----' '--------' | |/ '-----'
- ; ^ | 1-g**2
- ; | g |
- ; | /| |
- ; +-----< |---------+
- ; \|
- ;...........................................................................
- ;
- ; one multi-tap fir structure - to handle early reflections
- ;
- ; followed by 4 parallel comb (iir) filters (each comb having
- ; a first order LPF in its feedback loop
- ;
- ; followed by an 'allpass' reverberator whose output is then
- ; delayed so that its first output follows after the last "early
- ; reflection" output
- ;
- ;__________________________________________________________________________
- ;
- opt cex
- page 132
-
- ;--------------------------------------------------constant declarations
- adc equ $ffef ; ADC address
- dac equ $ffef ; DAC address
-
- ntap equ 7 ; number of taps EARLY REFLECTION FIR
- tapmod equ ntap-1 ; number of taps minus 1
- dlymx equ 4000 ; length of delay line in samples
-
- cmbdly1 equ 2205 ; COMB FILTER CONSTANTS
- cmbdly2 equ 2690 ; delay values (in samples)
- cmbdly3 equ 3175
- cmbdly4 equ 3440
-
- cmbmod1 equ 3490 ; modulo for comb #1 delay line THESE ARE
- cmbmod2 equ 3490 ; " " #2 " " ALSO THE
- cmbmod3 equ 3490 ; " " #3 " " MAX DELAYS
- cmbmod4 equ 3490 ; " " #4 " " ALLOWED FOR
- ; CHOSEN DSM
- ; VALUE
-
- untrvbdly equ 265 ; delay UNIT (or ALLPASS)
- unt_g equ 0.7 ; gains (g) REVERBERATOR
- neg_g equ -unt_g ; (-g)
- one_m_g2 equ (1-unt_g*unt_g) ; " (1-g**2)
-
-
- cmb_g equ 0.85 ; (OVERALL) COMB FILTER FEEDBACK GAIN
- ; controls reverb decay time: smaller
- ; values give quicker decay, larger
- ; values yield slower decay
-
- lpf1 equ 0.408 ; lpf filter coefficient in the
- lpf2 equ 0.448 ; feedback loop of the combs,
- lpf3 equ 0.476 ; these LPF's simulate the high freq
- lpf4 equ 0.496 ; attentuation in real acoustic reverb
-
- fdbck1 equ cmb_g*(1-lpf1) ; actual comb feedback gain
- fdbck2 equ cmb_g*(1-lpf2) ; is determined by the lpf filter
- fdbck3 equ cmb_g*(1-lpf3) ; coefficient and the overall feed-
- fdbck4 equ cmb_g*(1-lpf4) ; back gain to insure stability
-
-
- aligndly equ 1305 ; alignment delay (see diagram above)
- alignmod equ 1390 ; " mod
-
-
- reverbg equ 0.35 ; reverberation output gain value
- firg equ 0.15 ; early rflctn FIR output gain value
- dryg equ 0.9999-(reverbg+firg) ; dry signal gain is rest
- ; CHOOSE THE MIX YOU LIKE
-
-
- org x:0
- chead1 dsm 3500 ; allocates 3500 data spaces for use as
- chead2 dsm 3500 ; comb filter tap delay lines, CHEAD1 refers
- chead3 dsm 3500 ; to the Comb filter HEAD (beginning) for
- chead4 dsm 3500 ; filter #1
-
- org x:$0f00
- ofst_bf dsm ntap ; this reserves "ntap" contiguous addresses
- org x:ofst_bf ; starting at the closest appropriate modulo
- ofst0 dc 1 ; x address space. Then starts filling the
- ofst1 dc 877 ; offset buffer at this location with
- ofst2 dc 1561 ; the right delay values for the
- ofst3 dc 1716 ; EARLY REFLECTION FIR
- ofst4 dc 1826
- ofst5 dc 3083 ; IMPORTANT - to get no delay for the first
- ofst6 dc 3510 ; early reflection, use a "1". This is due the use
- ; of an instruction code pre-decrement, a "0" value
- ; will cause a maximum delay equal to the tap delay
- ; line length
-
-
-
- untdly dc untrvbdly ; define the UNIT REVERBERATOR delay
- untg1 dc unt_g ; " " g
- untg2 dc neg_g ; " " " -g
- untg3 dc one_m_g2 ; " " (1-g**2)
- untmod dc untrvbdly-1 ; modulo for " "
-
- algndly dc aligndly
- algnmod dc alignmod
-
- org y:$0f00
- gain_bf dsm ntap
- org y:gain_bf ; starting at y address zero this reserves
- ; "ntap" contiguous addresses then starts
- ; filling these addresses with the desired
- gain0 dc 0.213 ; tap "gain" values for EARLY REFLECTION FIR
- gain1 dc 0.217 ; recommended by moorer
- gain2 dc 0.174 ;
- gain3 dc 0.135 ; it is recommended to keep many early
- gain4 dc 0.153 ; reflection returns, as these are fed into
- gain5 dc 0.157 ; comb filters, than can contribute greatly
- gain6 dc 0.051 ; to the later impulse response density
-
- rvbgain dc reverbg ; total reverberation gain
- firgain dc firg ; early reflection gain
- drygain dc dryg ; dry signal gain
-
- org y:0
- c1g1 dc lpf1 ; comb #1 g1 (LPF gain)
- c2g1 dc lpf2 ; #2
- c3g1 dc lpf3 ; #3
- c4g1 dc lpf4 ; #4
-
-
- c1g2 dc fdbck1 ; feedback gain derived from
- c2g2 dc fdbck2 ; cig2= g * (1 - cig1) where i=comb#
- c3g2 dc fdbck3
- c4g2 dc fdbck4
-
-
- sample ds 1 ; input sample storage address
- firout ds 1 ; early ref FIR OUTput storage address
-
- c1out ds 1 ; COMB filter #1 output storage address
- c2out ds 1 ; " " #2 " " "
- c3out ds 1 ; " " #3 " " "
- c4out ds 1 ; " " #4 " " "
-
- lpfst1 ds 1 ; " " #1 Low Pass Filter state
- lpfst2 ds 1 ; " " #2 " " " "
- lpfst3 ds 1 ; " " #3 " " " "
- lpfst4 ds 1 ; " " #4 " " " "
-
- ; allocates modulo memory for the unit
- udlyln dsm 300 ; (allpass) reverberator delay line
-
- algndlyln dsm 1400 ; allocates modulo memory for alignment delay
- ; line
-
- dlyline dsm dlymx ; allocates mod memory for the FIR delay line
-
- ;--------------------------------------------------------------------------
- org p:$40 ; program start address
-
- ; Set up ADS board in case of force break instead of force reset
- movep #0,x:$FFFE ;set bcr to zero
- movec #0,sp ;init stack pointer
- movec #0,sr ;clear loop flag
-
- ; Set up the SSI for operation with the DSP56ADC16EVB
- ; The following code sets port C to function as SCI/SSI
- move #$0,a0 ;zero PCC to cycle it
- movep a0,x:$FFE1
- move #$0001ff,a0
- movep a0,x:$FFE1 ;write PCC
-
- ; The following code sets the SSI CRA and CRB control registers for external
- ; continuous clock, synchronous, normal mode.
- move #$004000,a0 ;CRA pattern for word length=16 bits
- movep a0,x:$FFEC
- move #$003200,a0 ;CRB pattern for continous ck,sych,normal mode
- movep a0,x:$FFED ;word long frame sync: FSL=0;ext ck/fs
-
- ; -------------------------------------------------------------------------
- ; initialize registers MO,RO, etc
- move #dlymx-1,m0 ; tap line modulus
- move #dlyline,r0 ; start of delay line
- move #0,n0 ;
-
- move #tapmod,m1 ; tap gain line modulo
- move #gain_bf,r1 ; tap gain & tap delay pointer
-
- move #cmbmod1,m2 ; initialize the modulo registers
- move #cmbmod2,m3 ; for comb filter buffers 1 thru 5
- move #cmbmod3,m4
- move #cmbmod4,m5
-
- move #cmbdly1,n2 ; initialize the offset register
- move #cmbdly2,n3 ; for Comb filters 1 thru 5
- move #cmbdly3,n4
- move #cmbdly4,n5
-
- move #chead1,r2 ; initialize the pointer values for
- move #chead2,r3 ; Comb filters 1 thru 5
- move #chead3,r4
- move #chead4,r5
-
- move x:algnmod,m6 ; initialize alignment delay line
- move x:algndly,n6 ; offset, modulo, and pointer registers
- move #algndlyln,r6
-
- move x:untmod,m7 ; initialize unit reverberator (allpass)
- move x:untdly,n7 ; offset, modulo, and pointer registers
- move #udlyln,r7
-
- ;---------------------------------------------------------------------------
- ; The following code polls the RDF flag in the SSI-SR and waits for RDF=1
- ; and then reads the RX register to retrieve the data from the A/D converter.
- ; Sample rate is controlled by DSP56ADC16 board.
-
- poll jclr #7,x:$FFEE,poll ;loop until RDF bit = 1
- movep x:adc,a ;get A/D converter data
- ;---------------------------------------------------------------------------
- ; asr a
- asr a ; obtain data sample
- ; and shift right for headroom
- move a,y:sample ; keep dry sample
-
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- ; FIR for early reflections
- move a,y:(r0)- ; push sample into delay line
- clr a
- do #ntap,fir ; loop over the (ntaps-1),exclude fb tap now
- move x:(r1),n0 ; put the tap offset value into N0
- move y:(r1)+,y1 ; " " " gain " " Y
- move y:(r0+n0),x1 ; get delayed sample
- mac x1,y1,a ; MAC gain and sample
- fir move a,y:firout ; save FIR OUTput to y memory
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- ; COMB 1
- move y:firout,a ; comb filter #1 with LPF in feed back
- move x:(r2+n2),b ; get delayed sample & put in b
- move b,y:c1out ; move output to y memory space
-
- move y:c1g1,x1 ; get LPF filter coeff
- move y:lpfst1,y1 ; get LPF filter state
- mac x1,y1,b ; compute LPF output
- move b,y:lpfst1 ; save LPF output to LPF state
-
- move y:c1g2,x1 ; get feedback coefficient
- move b,y1 ; put LPF output in Y1
- mac x1,y1,a ; compute feedback term in A
- move a,x:(r2)- ; store output into delay queue
-
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- ; COMB 2
- move y:firout,a ; comb filter #1 with LPF in feed back
- move x:(r3+n3),b ; get delayed sample & put in b
- move b,y:c2out ; move output to y memory space
-
- move y:c2g1,x1 ; get LPF filter coeff
- move y:lpfst2,y1 ; get LPF filter state
- mac x1,y1,b ; compute LPF output
- move b,y:lpfst2 ; save LPF output to LPF state
-
- move y:c2g2,x1 ; get feedback coefficient
- move b,y1 ; put LPF output in Y1
- mac x1,y1,a ; compute feedback term in A
- move a,x:(r3)- ; store output into delay queue
-
-
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- ; COMB 3
- move y:firout,a ; comb filter #1 with LPF in feed back
- move x:(r4+n4),b ; get delayed sample & put in b
- move b,y:c3out ; move output to y memory space
-
- move y:c3g1,x1 ; get LPF filter coeff
- move y:lpfst3,y1 ; get LPF filter state
- mac x1,y1,b ; compute LPF output
- move b,y:lpfst3 ; save LPF output to LPF state
-
- move y:c3g2,x1 ; get feedback coefficient
- move b,y1 ; put LPF output in Y1
- mac x1,y1,a ; compute feedback term in A
- move a,x:(r4)- ; store output into delay queue
- ; - - - - - - - - - - - - - - - - -
- ; COMB 4
- move y:firout,a ;
- move x:(r5+n5),b ; get delayed sample & put in b
- move b,y:c4out ; move output to y memory space
-
- move y:c4g1,x1 ; get LPF filter coeff
- move y:lpfst4,y1 ; get LPF filter state
- mac x1,y1,b ; compute LPF output
- move b,y:lpfst4 ; save LPF output to LPF state
-
- move y:c4g2,x1 ; get feedback coefficient
- move b,y1 ; put LPF output in Y1
- mac x1,y1,a ; compute feedback term in A
- move a,x:(r5)- ; store output into delay queue
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- move y:c1out,x1 ; add output of all four combs
- move y:c2out,a
- add x1,a
- move y:c3out,x1
- add x1,a
- move y:c4out,x1
- add x1,a
- ; asr a
- ; - - - - - - - - - - - - - - - - - -
- ; all pass unit reverberator
- clr b
- move a,x1
- move x:untg2,y1
- mac x1,y1,b
-
- move y:(r7+n7),x1 ; get delayed sample
- move x:untg3,y1 ; get gain (1-g**2)
- mac x1,y1,b ; MAC into b for output (B CONTAINS OUTPUT)
-
- move x:untg1,y1 ; get gain g
- mac x1,y1,a
- move a,y:(r7)- ; put new+g*delayed into delay line/inc r7
- move b,y:(r6)- ;store the output in a queue for align delay
- ; - - - - - - - - - - - - -
- move y:(r6+n6),y1 ; get the delayed unit rvb sample
- move y:rvbgain,x1 ; and the reverb gain
- mpy x1,y1,a
-
- move y:firout,y1 ; get the early reflection FIR output sample
- move y:firgain,x1 ; and FIR gain
- mac x1,y1,a
-
- move y:sample,y1 ; mix in the dry sample
- move y:drygain,x1 ; by the dry gain
- mac x1,y1,a ; A now contains the output sample
- asr a
- ; - - - - - - - - - - - - - - - - - - - - - - - -
- ; Write DSP56ADC16 A/D converter data to the PCM-56
-
- move a,x:dac ;write the PCM-56 D/A via SSI xmt reg.
- jmp poll ;loop indefinitely
-
- end
- ə
- ə